//=========================================================================== // E6 GROWTH BY SEGREGATED DIFFUSION LIMITED AGGREGATION // Inspired by Gary William Flake's COMPUTATIONAL BEAUTY OF NATURE // Figure 10.5, pages 74-75. Revised, 7 April 2015 == //=========================================================================== #include #pragma hdrstop #include "Unit1.h" #include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //=========================================================================== // VARIABLES //=========================================================================== #define CYAN 1 #define MAGENTA 2 #define YELLOW 3 #define WORLD 500 int worldAge[WORLD][WORLD]; // the world stored as the age of fixed agents int worldKind[WORLD][WORLD]; // the kind of fixed agents int kind; int x, y; // the position of the agent int tryX, tryY; // the trial position of the agent int leftX, rigtX; // the agent's neighborhood int toppY, botmY; // the agent's neighborhood int nhoodPattern1[3][3]; // first neighborhood pattern int nhoodPattern2[3][3]; // second neighborhood pattern int nhoodPattern3[3][3]; // third neighborhood pattern int nhoodPattern4[3][3]; // forth neighborhood pattern bool pattern1found; // neighborhood pattern1found bool pattern2found; // neighborhood pattern2found bool pattern3found; // neighborhood pattern3found bool pattern4found; // neighborhood pattern4found // logical variables to choose options bool stop = false; bool stick = false; bool showPath = false; bool showSlow = false; bool draw = false; bool usePatterns = false; // other variables bool showAges = true; int side; int pathStep; int pathLength = 500000; int colorRange = 30000; int agents = 0; int numNeighbors = 0; // number of neighbors int sumAgeNeighbors = 0; // sum of the ages of neighbors int cyanNeighbors = 0; int magentaNeighbors = 0; int yellowNeighbors = 0; int ruleChoice = 0; int e, s; int rE, rS; int wE, wS; TColor background = clGray; int neighborsToStick = 1; int neighborsToDelete = 1; int percentToDelete = 30; float floatPercentToDelete = 0.30; int cycles = 2; int movementChoice = 0; //=========================================================================== // FUNCTIONS //=========================================================================== //---------------------------------------------------------------- Color Ramp int colorRamp(int range, int value) { if (range == 0) { range = 1; } int pixelDistanceAlongPath = (value * 1792) / range; int red, green, blue; // Which edge of the color cube are we on? if (pixelDistanceAlongPath < 256) { // Edge 1 from BLACK to BLUE red=0; green=0; blue=pixelDistanceAlongPath; } else if (pixelDistanceAlongPath < 512) { // Edge 2 from BLUE to CYAN red =0; green=pixelDistanceAlongPath-256; blue=255; } else if (pixelDistanceAlongPath < 768) { // Edge 3 from CYAN to GREEN red =0; green =255; blue= 255-(pixelDistanceAlongPath-512); } else if (pixelDistanceAlongPath < 1024) { // Edge 4 from GREEN to YELLOW red= (pixelDistanceAlongPath-768); green =255; blue =0; } else if (pixelDistanceAlongPath <1280) { // Edge 5 from YELLOW to RED red =255; green=255-(pixelDistanceAlongPath-1024); blue =0; } else if (pixelDistanceAlongPath < 1536) { // Edge 6 from RED to MAGENTA red =255; green=0; blue=pixelDistanceAlongPath -1280; } else { // Edge 7 from MAGENTA to WHITE red =255; green=pixelDistanceAlongPath-1536; blue =255; } return (RGB(red, green, blue)); } //------------------------------------------ Set Neighborhood Search Patterns void setNhoodPatterns (void) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { nhoodPattern1[i][j] = 99; // to indicate "don't care" if (Form1->StringGrid1->Cells[i][j] == "0") nhoodPattern1[i][j] = 0; if (Form1->StringGrid1->Cells[i][j] == "1") nhoodPattern1[i][j] = 1; nhoodPattern2[i][j] = 99; // to indicate "don't care" if (Form1->StringGrid2->Cells[i][j] == "0") nhoodPattern2[i][j] = 0; if (Form1->StringGrid2->Cells[i][j] == "1") nhoodPattern2[i][j] = 1; nhoodPattern3[i][j] = 99; // to indicate "don't care" if (Form1->StringGrid3->Cells[i][j] == "0") nhoodPattern3[i][j] = 0; if (Form1->StringGrid3->Cells[i][j] == "1") nhoodPattern3[i][j] = 1; nhoodPattern4[i][j] = 99; // to indicate "don't care" if (Form1->StringGrid4->Cells[i][j] == "0") nhoodPattern4[i][j] = 0; if (Form1->StringGrid4->Cells[i][j] == "1") nhoodPattern4[i][j] = 1; } } } //--------------------------------------------------------------- Render Ages void renderAges (void) { // for each and every cell for (int i = 0; i < WORLD; i++) { for (int j = 0; j < WORLD; j++) { // If no one is there, then color the cell black if (worldAge[i][j] == false) { Form1->PaintBox1->Canvas->Pixels[i][j] = background; } // If someone is there, then color the cell according to its age else { Form1->PaintBox1->Canvas->Pixels[i][j] = static_cast (colorRamp(colorRange, worldAge[i][j])); } } } } //-------------------------------------------------------------- Render Types void renderKinds (void) { // for each and every cell for (int i = 0; i < WORLD; i++) { for (int j = 0; j < WORLD; j++) { // If no one is there, then color the cell black if (worldKind[i][j] == false) { Form1->PaintBox1->Canvas->Pixels[i][j] = background; } if (worldKind[i][j] == 1) { Form1->PaintBox1->Canvas->Pixels[i][j] = clAqua; } if (worldKind[i][j] == 2) { Form1->PaintBox1->Canvas->Pixels[i][j] = clFuchsia; } if (worldKind[i][j] == 3) { Form1->PaintBox1->Canvas->Pixels[i][j] = clYellow; } } } } //--------------------------------------------------------------------- Reset void reset (void) { randomize(); // for each and every cell for (int i = 0; i < WORLD; i++) { for (int j = 0; j < WORLD; j++) { worldAge[i][j] = false; worldKind[i][j] = false; } } agents = 0; Form1->EditParticles->Text = 0; renderAges(); } //----------------------------------------------------------- Count Neighbors void countNeighbors (void) { numNeighbors = 0; sumAgeNeighbors = 0; cyanNeighbors = 0; magentaNeighbors = 0; yellowNeighbors = 0; for (rE = x - 1; rE < x + 2; rE++) { if (rE < 0) wE = WORLD - 1; else if (rE > WORLD - 1) wE = 0; else wE = rE; for (rS = y - 1; rS < y + 2; rS++) { if (rE == x && rS == y) continue; if (rS < 0) wS = WORLD - 1; else if (rS > WORLD - 1) wS = 0; else wS = rS; if (worldAge[wE][wS] > 0) numNeighbors++; if (worldKind[wE][wS] == 1) cyanNeighbors++; if (worldKind[wE][wS] == 2) magentaNeighbors++; if (worldKind[wE][wS] == 3) yellowNeighbors++; sumAgeNeighbors += worldAge[wE][wS]; } } } //-------------------------------------------------- Check Ruled Neighborhood void checkRuledNeighborhood (void) { stick = false; countNeighbors(); switch (ruleChoice) { case 0: { if (numNeighbors == neighborsToStick) stick = true; break; } case 1: { if (numNeighbors >= neighborsToStick) stick = true; break; } case 2: { if (numNeighbors < neighborsToStick && numNeighbors > 0) stick = true; break; } case 3: { if (numNeighbors == 1 || numNeighbors == 3) stick = true; break; } case 4: { if (numNeighbors == 2 || numNeighbors == 4) stick = true; break; } case 5: { if (numNeighbors == 1 && (sumAgeNeighbors < (floatPercentToDelete * agents))) { stick = true; } break; } case 6: { // TBar preference for same kinds if (kind == CYAN) { if (cyanNeighbors >= neighborsToStick) { stick = true; } } if (kind == MAGENTA) { if (magentaNeighbors >= neighborsToStick) { stick = true; } } if (kind == YELLOW) { if (yellowNeighbors >= neighborsToStick) { stick = true; } } break; } case 7: { // TBar preference for different kinds C>M, M>M, Y>C if (kind == CYAN) { if (magentaNeighbors >= neighborsToStick) { stick = true; } } if (kind == MAGENTA) { if (magentaNeighbors >= neighborsToStick) { stick = true; } } if (kind == YELLOW) { if (cyanNeighbors >= neighborsToStick) { stick = true; } } break; } case 8: { // TBar preference for different kinds C>MY, M>M, Y>C if (kind == CYAN) { if (magentaNeighbors >= neighborsToStick && yellowNeighbors >= neighborsToStick) { stick = true; } } if (kind == MAGENTA) { if (magentaNeighbors >= neighborsToStick) { stick = true; } } if (kind == YELLOW) { if (cyanNeighbors >= neighborsToStick) { stick = true; } } break; } case 9: { // TBar preference for different kinds C>CM, M>Y, Y>C if (kind == CYAN) { if (magentaNeighbors >= neighborsToStick && cyanNeighbors >= neighborsToStick) { stick = true; } } if (kind == MAGENTA) { if (yellowNeighbors >= neighborsToStick) { stick = true; } } if (kind == YELLOW) { if (cyanNeighbors >= neighborsToStick) { stick = true; } } break; } } if (stick == true) { worldAge[x][y] = agents; worldKind[x][y] = kind; if (showAges) { Form1->PaintBox1->Canvas->Pixels[x][y] = static_cast(colorRamp(colorRange, agents)); } else { if (kind == 1) { Form1->PaintBox1->Canvas->Pixels[x][y] = clAqua; } if (kind == 2) { Form1->PaintBox1->Canvas->Pixels[x][y] = clFuchsia; } if (kind == 3) { Form1->PaintBox1->Canvas->Pixels[x][y] = clYellow; } } Application->ProcessMessages(); } } //---------------------------------------------- Check Patterned Neighborhood void checkPatternedNeighborhood (void) { stick = false; // get valid wrap-around coordinates for the neighborhood leftX = x - 1; if (leftX < 0) leftX = WORLD - 1; rigtX = x + 1; if (rigtX > WORLD - 1) rigtX = 0; toppY = y - 1; if (toppY < 0) toppY = WORLD - 1; botmY = y + 1; if (botmY > WORLD - 1) botmY = 0; pattern1found = true; // cell 1 if ( !( (nhoodPattern1[0][0] == 0) && (worldAge[leftX][toppY] == 0) || (nhoodPattern1[0][0] == 1) && (worldAge[leftX][toppY] > 0) || (nhoodPattern1[0][0] == 99) ) ) {pattern1found = false; goto endPattern1;} // cell 2 if ( !( (nhoodPattern1[1][0] == 0) && (worldAge[x][toppY] == 0) || (nhoodPattern1[1][0] == 1) && (worldAge[x][toppY] > 0) || (nhoodPattern1[1][0] == 99) ) ) {pattern1found = false; goto endPattern1;} // cell 3 if ( !( (nhoodPattern1[2][0] == 0) && (worldAge[rigtX][toppY] == 0) || (nhoodPattern1[2][0] == 1) && (worldAge[rigtX][toppY] > 0) || (nhoodPattern1[2][0] == 99) ) ) {pattern1found = false; goto endPattern1;} // cell 4 if ( !( (nhoodPattern1[0][1] == 0) && (worldAge[leftX][y] == 0) || (nhoodPattern1[0][1] == 1) && (worldAge[leftX][y] > 0) || (nhoodPattern1[0][1] == 99) ) ) {pattern1found = false; goto endPattern1;} // cell 5 - that's the agent, ignore it // cell 6 if ( !( (nhoodPattern1[2][1] == 0) && (worldAge[rigtX][y] == 0) || (nhoodPattern1[2][1] == 1) && (worldAge[rigtX][y] > 0) || (nhoodPattern1[2][1] == 99) ) ) {pattern1found = false; goto endPattern1;} // cell 7 if ( !( (nhoodPattern1[0][2] == 0) && (worldAge[leftX][botmY] == 0) || (nhoodPattern1[0][2] == 1) && (worldAge[leftX][botmY] > 0) || (nhoodPattern1[0][2] == 99) ) ) {pattern1found = false; goto endPattern1;} // cell 8 if ( !( (nhoodPattern1[1][2] == 0) && (worldAge[x][botmY] == 0) || (nhoodPattern1[1][2] == 1) && (worldAge[x][botmY] > 0) || (nhoodPattern1[1][2] == 99) ) ) {pattern1found = false; goto endPattern1;} // cell 9 if ( !( (nhoodPattern1[2][2] == 0) && (worldAge[rigtX][botmY] == 0) || (nhoodPattern1[2][2] == 1) && (worldAge[rigtX][botmY] > 0) || (nhoodPattern1[2][2] == 99) ) ) {pattern1found = false; goto endPattern1;} endPattern1: pattern2found = true; // cell 1 if ( !( (nhoodPattern2[0][0] == 0) && (worldAge[leftX][toppY] == 0) || (nhoodPattern2[0][0] == 1) && (worldAge[leftX][toppY] > 0) || (nhoodPattern2[0][0] == 99) ) ) {pattern2found = false; goto endPattern2;} // cell 2 if ( !( (nhoodPattern2[1][0] == 0) && (worldAge[x][toppY] == 0) || (nhoodPattern2[1][0] == 1) && (worldAge[x][toppY] > 0) || (nhoodPattern2[1][0] == 99) ) ) {pattern2found = false; goto endPattern2;} // cell 3 if ( !( (nhoodPattern2[2][0] == 0) && (worldAge[rigtX][toppY] == 0) || (nhoodPattern2[2][0] == 1) && (worldAge[rigtX][toppY] > 0) || (nhoodPattern2[2][0] == 99) ) ) {pattern2found = false; goto endPattern2;} // cell 4 if ( !( (nhoodPattern2[0][1] == 0) && (worldAge[leftX][y] == 0) || (nhoodPattern2[0][1] == 1) && (worldAge[leftX][y] > 0) || (nhoodPattern2[0][1] == 99) ) ) {pattern2found = false; goto endPattern2;} // cell 5 - that's the agent, ignore it // cell 6 if ( !( (nhoodPattern2[2][1] == 0) && (worldAge[rigtX][y] == 0) || (nhoodPattern2[2][1] == 1) && (worldAge[rigtX][y] > 0) || (nhoodPattern2[2][1] == 99) ) ) {pattern2found = false; goto endPattern2;} // cell 7 if ( !( (nhoodPattern2[0][2] == 0) && (worldAge[leftX][botmY] == 0) || (nhoodPattern2[0][2] == 1) && (worldAge[leftX][botmY] > 0) || (nhoodPattern2[0][2] == 99) ) ) {pattern2found = false; goto endPattern2;} // cell 8 if ( !( (nhoodPattern2[1][2] == 0) && (worldAge[x][botmY] == 0) || (nhoodPattern2[1][2] == 1) && (worldAge[x][botmY] > 0) || (nhoodPattern2[1][2] == 99) ) ) {pattern2found = false; goto endPattern2;} // cell 9 if ( !( (nhoodPattern2[2][2] == 0) && (worldAge[rigtX][botmY] == 0) || (nhoodPattern2[2][2] == 1) && (worldAge[rigtX][botmY] > 0) || (nhoodPattern2[2][2] == 99) ) ) {pattern2found = false; goto endPattern2;} endPattern2: pattern3found = true; // cell 1 if ( !( (nhoodPattern3[0][0] == 0) && (worldAge[leftX][toppY] == 0) || (nhoodPattern3[0][0] == 1) && (worldAge[leftX][toppY] > 0) || (nhoodPattern3[0][0] == 99) ) ) {pattern3found = false; goto endPattern3;} // cell 2 if ( !( (nhoodPattern3[1][0] == 0) && (worldAge[x][toppY] == 0) || (nhoodPattern3[1][0] == 1) && (worldAge[x][toppY] > 0) || (nhoodPattern3[1][0] == 99) ) ) {pattern3found = false; goto endPattern3;} // cell 3 if ( !( (nhoodPattern3[2][0] == 0) && (worldAge[rigtX][toppY] == 0) || (nhoodPattern3[2][0] == 1) && (worldAge[rigtX][toppY] > 0) || (nhoodPattern3[2][0] == 99) ) ) {pattern3found = false; goto endPattern3;} // cell 4 if ( !( (nhoodPattern3[0][1] == 0) && (worldAge[leftX][y] == 0) || (nhoodPattern3[0][1] == 1) && (worldAge[leftX][y] > 0) || (nhoodPattern3[0][1] == 99) ) ) {pattern3found = false; goto endPattern3;} // cell 5 - that's the agent, ignore it // cell 6 if ( !( (nhoodPattern3[2][1] == 0) && (worldAge[rigtX][y] == 0) || (nhoodPattern3[2][1] == 1) && (worldAge[rigtX][y] > 0) || (nhoodPattern3[2][1] == 99) ) ) {pattern3found = false; goto endPattern3;} // cell 7 if ( !( (nhoodPattern3[0][2] == 0) && (worldAge[leftX][botmY] == 0) || (nhoodPattern3[0][2] == 1) && (worldAge[leftX][botmY] > 0) || (nhoodPattern3[0][2] == 99) ) ) {pattern3found = false; goto endPattern3;} // cell 8 if ( !( (nhoodPattern3[1][2] == 0) && (worldAge[x][botmY] == 0) || (nhoodPattern3[1][2] == 1) && (worldAge[x][botmY] > 0) || (nhoodPattern3[1][2] == 99) ) ) {pattern3found = false; goto endPattern3;} // cell 9 if ( !( (nhoodPattern3[2][2] == 0) && (worldAge[rigtX][botmY] == 0) || (nhoodPattern3[2][2] == 1) && (worldAge[rigtX][botmY] > 0) || (nhoodPattern3[2][2] == 99) ) ) {pattern3found = false; goto endPattern3;} endPattern3: pattern4found = true; // cell 1 if ( !( (nhoodPattern4[0][0] == 0) && (worldAge[leftX][toppY] == 0) || (nhoodPattern4[0][0] == 1) && (worldAge[leftX][toppY] > 0) || (nhoodPattern4[0][0] == 99) ) ) {pattern4found = false; goto endPattern4;} // cell 2 if ( !( (nhoodPattern4[1][0] == 0) && (worldAge[x][toppY] == 0) || (nhoodPattern4[1][0] == 1) && (worldAge[x][toppY] > 0) || (nhoodPattern4[1][0] == 99) ) ) {pattern4found = false; goto endPattern4;} // cell 3 if ( !( (nhoodPattern4[2][0] == 0) && (worldAge[rigtX][toppY] == 0) || (nhoodPattern4[2][0] == 1) && (worldAge[rigtX][toppY] > 0) || (nhoodPattern4[2][0] == 99) ) ) {pattern4found = false; goto endPattern4;} // cell 4 if ( !( (nhoodPattern4[0][1] == 0) && (worldAge[leftX][y] == 0) || (nhoodPattern4[0][1] == 1) && (worldAge[leftX][y] > 0) || (nhoodPattern4[0][1] == 99) ) ) {pattern4found = false; goto endPattern4;} // cell 5 - that's the agent, ignore it // cell 6 if ( !( (nhoodPattern4[2][1] == 0) && (worldAge[rigtX][y] == 0) || (nhoodPattern4[2][1] == 1) && (worldAge[rigtX][y] > 0) || (nhoodPattern4[2][1] == 99) ) ) {pattern4found = false; goto endPattern4;} // cell 7 if ( !( (nhoodPattern4[0][2] == 0) && (worldAge[leftX][botmY] == 0) || (nhoodPattern4[0][2] == 1) && (worldAge[leftX][botmY] > 0) || (nhoodPattern4[0][2] == 99) ) ) {pattern4found = false; goto endPattern4;} // cell 8 if ( !( (nhoodPattern4[1][2] == 0) && (worldAge[x][botmY] == 0) || (nhoodPattern4[1][2] == 1) && (worldAge[x][botmY] > 0) || (nhoodPattern4[1][2] == 99) ) ) {pattern4found = false; goto endPattern4;} // cell 9 if ( !( (nhoodPattern4[2][2] == 0) && (worldAge[rigtX][botmY] == 0) || (nhoodPattern4[2][2] == 1) && (worldAge[rigtX][botmY] > 0) || (nhoodPattern4[2][2] == 99) ) ) {pattern4found = false; goto endPattern4;} endPattern4: if ( pattern1found || pattern2found || pattern3found || pattern4found ) { // then stick = true; worldAge[x][y] = agents; worldKind[x][y] = kind; if (showAges) { Form1->PaintBox1->Canvas->Pixels[x][y] = static_cast(colorRamp(colorRange, agents)); } else { if (kind == 1) { Form1->PaintBox1->Canvas->Pixels[x][y] = clAqua; } if (kind == 2) { Form1->PaintBox1->Canvas->Pixels[x][y] = clFuchsia; } if (kind == 3) { Form1->PaintBox1->Canvas->Pixels[x][y] = clYellow; } } } Application->ProcessMessages(); } //-------------------------------------------------------------------- Wander void wander (void) { while (stick == false && stop == false) { int attempt = 0; again: if (movementChoice == 0) { tryX = (x + random(3) - 1); // attempt to move randomly tryY = (y + random(3) - 1); } if (movementChoice == 1) { tryX = random(WORLD); // attempt to move randomly tryY = random(WORLD); } tryX = (tryX + WORLD) % WORLD; tryY = (tryY + WORLD) % WORLD; attempt++; if (attempt > 10000) stop = true; if (worldAge[tryX][tryY] > 0) goto again; // if occupied, attempt again x = tryX; // if not, move y = tryY; if (showPath) { // render wanderer path if selected // render path in colors if selected Form1->PaintBox1->Canvas->Pixels[x][y] = static_cast(colorRamp(pathLength, pathStep)); if (showSlow) Sleep(1); Application->ProcessMessages(); } if (usePatterns) { checkPatternedNeighborhood(); } else { checkRuledNeighborhood(); } if (worldAge[x][y] > 0) break; pathStep++; Application->ProcessMessages(); } } //--------------------------------------------------------- Release an Agent void releaseAnAgent (void) { // Pick a position along an edge at random kind = random(3) + 1; switch (random(4)) { case 0: { x = random(WORLD); y = 0; break; } case 1: { x = random(WORLD); y = WORLD - 1; break; } case 2: { x = 0; y = random(WORLD); break; } case 3: { x = WORLD - 1; y = random(WORLD); break; } } agents++; } //---------------------------------------------------------------------- Run void run (void) { while (stop == false) { if (showPath) { if (showAges) renderAges(); else renderKinds(); } Application->ProcessMessages(); stick = false; releaseAnAgent(); Form1->EditParticles->Text = agents; pathStep = 0; wander(); Application->ProcessMessages(); } } //----------------------------------------------------------------- open file void open (void) { int i, j; if (Form1->OpenDialog1->Execute()) { ifstream infile(Form1->OpenDialog1->FileName.c_str()); for (i = 0; i < WORLD; i++) { for (j = 0; j < WORLD; j++) { infile >> worldAge[i][j]; infile >> worldKind[i][j]; } } infile >> agents; infile.close(); Form1->OpenDialog1->DestroyComponents(); Form1->EditParticles->Text = agents; showAges = true; colorRange = agents; renderAges(); } } //----------------------------------------------------------------- save file void save (void) { int i, j; if (Form1->SaveDialog1->Execute()) { ofstream outfile(Form1->SaveDialog1->FileName.c_str()); for (i = 0; i < WORLD; i++) { for (j = 0; j < WORLD; j++) { outfile << worldAge[i][j] << " "; outfile << worldKind[i][j] << " "; } outfile << endl; } outfile << agents << " "; outfile << endl; outfile.close(); Form1->SaveDialog1->DestroyComponents(); } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //----------------------------------------------------------------- Form Show void __fastcall TForm1::FormShow(TObject *Sender) { randomize(); reset(); } //---------------------------------------------------------------- Form Paint void __fastcall TForm1::FormPaint(TObject *Sender) { // if (showAges) renderAges(); // else renderKinds(); } //------------------------------------------------------- PaintBox Mouse Down void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if ( X < WORLD && Y < WORLD ) { // put someone there agents++; worldAge[X][Y] = agents; worldKind[X][Y] = agents % 3 + 1; // random(3) + 1; Form1->PaintBox1->Canvas->Pixels[X][Y] = clWhite; } Form1->EditParticles->Text = agents; draw = true; } //------------------------------------------------------- PaintBox Mouse Move void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (draw) { // register a mouse click only if it is within range if ( X < WORLD && Y < WORLD ) { // put someone there agents++; worldAge[X][Y] = agents; worldKind[X][Y] = random(3) + 1; Form1->PaintBox1->Canvas->Pixels[X][Y] = clWhite; Form1->EditParticles->Text = agents; } Application->ProcessMessages(); } } //-------------------------------------------------------- PaintBox Mouse Up void __fastcall TForm1::PaintBox1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { draw = false; } //--------------------------------------------------------------- Run Button void __fastcall TForm1::ButtonRunClick(TObject *Sender) { stop = false; run(); } //-------------------------------------------------------------- Stop Button void __fastcall TForm1::ButtonStopClick(TObject *Sender) { stop = true; } //------------------------------------------------------------- Render Button void __fastcall TForm1::ButtonRenderClick(TObject *Sender) { if (showAges) renderAges(); else renderKinds(); } //-------------------------------------------------------------- Reset Button void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } //---------------------------------------------------- ComboBox Rules Change void __fastcall TForm1::ComboBoxRulesChange(TObject *Sender) { Form1->GroupBoxPatterns->Color = clGray; // inactive color Form1->GroupBoxRules->Color = clSilver; // active color ruleChoice = ComboBoxRules->ItemIndex; usePatterns = false; } //----------------------------------------------------- ComboBox Rules Click void __fastcall TForm1::GroupBoxRulesClick(TObject *Sender) { Form1->GroupBoxPatterns->Color = clGray; // inactive color Form1->GroupBoxRules->Color = clSilver; // active color ruleChoice = ComboBoxRules->ItemIndex; usePatterns = false; } //------------------------------------------------------- Set Pattern Button void __fastcall TForm1::ButtonSetPatternClick(TObject *Sender) { setNhoodPatterns(); Form1->GroupBoxPatterns->Color = clSilver; // active color Form1->GroupBoxRules->Color = clGray; // inactive color usePatterns = true; } //------------------------------------------------------ Warmer Colors Button void __fastcall TForm1::ButtonWarmerClick(TObject *Sender) { showAges = true; colorRange = colorRange * .9; renderAges(); } //--------------------------------------------------- Automatic Colors Button void __fastcall TForm1::ButtonAutoClick(TObject *Sender) { showAges = true; colorRange = agents; renderAges(); } //------------------------------------------------------ Cooler Colors Button void __fastcall TForm1::ButtonCoolerClick(TObject *Sender) { showAges = true; colorRange = colorRange * 1.1; renderAges(); } //---------------------------------------------------- Ice Cold Colors Button void __fastcall TForm1::ButtonIceColdClick(TObject *Sender) { showAges = true; colorRange = 100000; renderAges(); } //----------------------------------------------- RadioGroup Background Click void __fastcall TForm1::RadioGroupBackgroundClick(TObject *Sender) { if (RadioGroupBackground->ItemIndex == 0) background = clGray; if (RadioGroupBackground->ItemIndex == 1) background = clSilver; if (RadioGroupBackground->ItemIndex == 2) background = clBlack; if (RadioGroupBackground->ItemIndex == 3) background = clRed; if (RadioGroupBackground->ItemIndex == 4) background = clWhite; if (showAges) renderAges(); else renderKinds(); } //---------------------------------------------------------- Radio Group Path void __fastcall TForm1::RadioGroupPathClick(TObject *Sender) { if (Form1->RadioGroupPath->ItemIndex == 0) showPath = false; if (Form1->RadioGroupPath->ItemIndex == 1) { showPath = true; showSlow = false; } if (Form1->RadioGroupPath->ItemIndex == 2) { showPath = true; showSlow = true; } Application->ProcessMessages(); } //--------------------------------------------------------- That's All Folks void __fastcall TForm1::TrackBarNeighborsToDeleteChange(TObject *Sender) { neighborsToDelete = TrackBarNeighborsToDelete->Position; Form1->EditNeighbors->Text = neighborsToDelete; } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarPercentChange(TObject *Sender) { percentToDelete = TrackBarPercent->Position; floatPercentToDelete = float(percentToDelete) / 100.00; Form1->EditPercent->Text = percentToDelete; } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonNowClick(TObject *Sender) { // eliminate agents with this exact number of "neighbors" if (RadioGroupZap->ItemIndex == 0) { for (int i = 0; i < WORLD; i++) { for (int j = 0; j < WORLD; j++) { x = i; y = j; countNeighbors(); if (numNeighbors == neighborsToDelete) { worldAge[i][j] = 0; worldKind[i][j] = 0; } } } } // elimate the oldest "percent" number of agents if (RadioGroupZap->ItemIndex == 1) { for (int i = 0; i < WORLD; i++) { for (int j = 0; j < WORLD; j++) { if (worldAge[i][j] < agents * floatPercentToDelete) { worldAge[i][j] = 0; worldKind[i][j] = 0; } } } } colorRange = agents; if (showAges) renderAges(); else renderKinds(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonColorByKindClick(TObject *Sender) { showAges = false; renderKinds(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonOpenClick(TObject *Sender) { open(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonSaveClick(TObject *Sender) { save(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonCyclesClick(TObject *Sender) { // for each and every cell for (int i = 0; i < WORLD; i++) { for (int j = 0; j < WORLD; j++) { // If no one is there, then color the cell black if (worldAge[i][j] == false) { Form1->PaintBox1->Canvas->Pixels[i][j] = background; } // If someone is there, then color the cell according to its age else { Form1->PaintBox1->Canvas->Pixels[i][j] = static_cast (colorRamp(agents/cycles, worldAge[i][j]%(agents/cycles))); } } } } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarCyclesChange(TObject *Sender) { cycles = TrackBarCycles->Position; Form1->EditCycles->Text = cycles; } //--------------------------------------------------------------------------- void __fastcall TForm1::PaintBox1Paint(TObject *Sender) { if (showAges) renderAges(); else renderKinds(); } //--------------------------------------------------------------------------- void __fastcall TForm1::RadioGroupMovementChoiceClick(TObject *Sender) { movementChoice = RadioGroupMovementChoice->ItemIndex; } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarNeighborsChange(TObject *Sender) { neighborsToStick = TrackBarNeighbors->Position; Form1->EditNeighbors->Text = neighborsToStick; } //---------------------------------------------------------------------------